﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;
using IPC.Communication.Framework.Reflection;
using IPC.Communication.Framework.Serial;

namespace IPC.Communication.Framework.Profinet.Keyence
{
    public class KeyenceNanoSerial : SerialDeviceBase
    {
        public byte Station
        {
            get;
            set;
        }

        public bool UseStation
        {
            get;
            set;
        }

        public KeyenceNanoSerial()
        {
            base.ByteTransform = new RegularByteTransform();
            base.WordLength = 1;
        }

        protected override OperateResult InitializationOnOpen()
        {
            OperateResult<byte[]> operateResult = ReadFromCoreServer(KeyenceNanoHelper.GetConnectCmd(Station, UseStation));
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            if (operateResult.Content.Length > 2 && operateResult.Content[0] == 67 && operateResult.Content[1] == 67)
            {
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult("Check Failed: " + SoftBasic.ByteToHexString(operateResult.Content, ' '));
        }

        protected override OperateResult ExtraOnClose()
        {
            OperateResult<byte[]> operateResult = ReadFromCoreServer(KeyenceNanoHelper.GetDisConnectCmd(Station, UseStation));
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            if (operateResult.Content.Length > 2 && operateResult.Content[0] == 67 && operateResult.Content[1] == 70)
            {
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult("Check Failed: " + SoftBasic.ByteToHexString(operateResult.Content, ' '));
        }

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            return KeyenceNanoHelper.Read(this, address, length);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            return KeyenceNanoHelper.Write(this, address, value);
        }

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            return KeyenceNanoHelper.ReadBool(this, address, length);
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            return KeyenceNanoHelper.Write(this, address, value);
        }

        [HslMqttApi("WriteBoolArray", "")]
        public override OperateResult Write(string address, bool[] value)
        {
            return KeyenceNanoHelper.Write(this, address, value);
        }

        //[AsyncStateMachine(typeof(<WriteAsync>d__16))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool value)
        //{
        //    <WriteAsync>d__16 stateMachine = new <WriteAsync>d__16();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        [HslMqttApi("查询PLC的型号信息")]
        public OperateResult<KeyencePLCS> ReadPlcType()
        {
            return KeyenceNanoHelper.ReadPlcType(this);
        }

        [HslMqttApi("读取当前PLC的模式，如果是0，代表 PROG模式或者梯形图未登录，如果为1，代表RUN模式")]
        public OperateResult<int> ReadPlcMode()
        {
            return KeyenceNanoHelper.ReadPlcMode(this);
        }

        [HslMqttApi("设置PLC的时间")]
        public OperateResult SetPlcDateTime(DateTime dateTime)
        {
            return KeyenceNanoHelper.SetPlcDateTime(this, dateTime);
        }

        [HslMqttApi("读取指定软元件的注释信息")]
        public OperateResult<string> ReadAddressAnnotation(string address)
        {
            return KeyenceNanoHelper.ReadAddressAnnotation(this, address);
        }

        [HslMqttApi("从扩展单元缓冲存储器连续读取指定个数的数据，单位为字")]
        public OperateResult<byte[]> ReadExpansionMemory(byte unit, ushort address, ushort length)
        {
            return KeyenceNanoHelper.ReadExpansionMemory(this, unit, address, length);
        }

        [HslMqttApi("将原始字节数据写入到扩展的缓冲存储器，需要指定单元编号，偏移地址，写入的数据")]
        public OperateResult WriteExpansionMemory(byte unit, ushort address, byte[] value)
        {
            return KeyenceNanoHelper.WriteExpansionMemory(this, unit, address, value);
        }

        public override string ToString()
        {
            return String.Format("KeyenceNanoSerial[{0}:{1}]", base.PortName, base.BaudRate);
        }
    }
}